import { E_ItemID } from "../defs/item/E_ItemID";
import { E_LordGlobal } from "../defs/lord/E_LordGlobal";
import { E_PrayEffectType } from "../defs/lord/E_PrayEffectType";
import { E_ProtoTalent } from "../defs/lord/E_ProtoTalent";
import { E_TalentConfig } from "../defs/lord/E_TalentConfig";
import { E_MsgCode } from "../defs/proto/E_MsgCode";
import { CDBuyTimes } from "../excel/CDBuyTimes";
import { CDLordGlobal } from "../excel/CDLordGlobal";
import { CDLordTalent } from "../excel/CDLordTalent";
import { CDMath } from "../excel/CDMath";
import { CDUnitLv } from "../excel/CDUnitLv";
import { Player } from "../struct/Player";
import { SDPlayer } from "./SDPlayer";
import { SDPray } from "./SDPray";
import { SDHuangXiaoxi } from "./SDHuangXiaoxi";


/**
 * 数据-天赋
 */
export abstract class SDTalent {


    /**
     * 添加属性
     * @param player 
     * @param outList 
     */
    public static addMath(player: Player, outList: number[]): void {

        const ks = player.talent.getTalentLevelKeys();
        const vs = player.talent.getTalentLevelValues();

        for (let i = 0, len = ks.length; i < len; i++) {
            const config = CDLordTalent.getData(ks[i]);
            if (!config || 0 === config.math) {
                continue;
            }
            const mathId = config.math + vs[i];
            const mathConfig = CDMath.getData(mathId);
            if (!mathConfig) {
                continue;
            }
            SDPlayer.addMathConfig(mathConfig, outList);
        }
    }


    /**
     * 能否重置天赋
     * @param player 
     */
    public static isCanResetTalent(player: Player): boolean {
        const cost = this.getResetTalentCost(player);
        const have = player.getItemNum(E_ItemID.Diamonds);
        return cost <= have;
    }


    /**
     * 重置天赋消耗
     * @param player 
     */
    public static getResetTalentCost(player: Player): number {
        const maxTimes = CDLordGlobal.getData(E_LordGlobal.TalentResetMaxTimes).value;
        const idx = Math.min(player.talent.resetTimes, maxTimes - 1);
        let config = CDBuyTimes.getData(idx);
        if (!config) {
            const vs = CDBuyTimes.datas.getValues();
            config = vs[vs.length - 1];
        }
        if (config) {
            const cost = config.talentResetCost;
            return cost;
        }
        return 0;
    }


    /**
     * 最大技能等级
     * @param talentID 
     * @returns 
     */
    public static getTalentSkillMaxLevel(talentID: number): number {
        const config = CDLordTalent.getData(talentID);
        if (config) {
            return config.maxLv;
        }
        return 0;
    }


    /**
     * 是否可激活
     * @param player 
     * @param talentID 
     */
    public static isCanActivate(player: Player, talentID: number): E_ProtoTalent | E_MsgCode {
        const config = CDLordTalent.getData(talentID);
        if (!config) {
            return E_MsgCode.TalentConfigNotFind;
        }

        //已激活
        if (player.talent.getTalentLevel(talentID) > 0) {
            return E_ProtoTalent.Active;
        }

        //能力值等级
        if (0 !== config.reqMSkillLv) {
            const lv = player.talent.getTalentLevel(E_TalentConfig.MiddleTalentID);
            if (lv < config.reqMSkillLv) {
                return E_ProtoTalent.MSkillLvlNotEnough;
            }
        }

        //前置天赋
        {
            for (let i = 0, len = config.reqSkill.length; i < len; i++) {
                const talentID = config.reqSkill[i];
                const talentLevel = config.reqSkillLv[i] || 0;
                if (talentID > 0 && talentLevel > 0) {
                    const lv = player.talent.getTalentLevel(talentID);
                    if (lv < talentLevel) {
                        return E_ProtoTalent.PreSKillLevelNotEnough;
                    }
                }
            }
        }

        return 0;
    }


    /**
    * 是否可升级
    * @param player 
    * @param talentID 
    */
    public static isCanLevelUp(player: Player, talentID: number): E_ProtoTalent | E_MsgCode {
        const config = CDLordTalent.getData(talentID);
        if (!config) {
            return E_MsgCode.TalentConfigNotFind;
        }

        const lv = player.talent.getTalentLevel(talentID);
        if (0 === lv) {
            // return E_ProtoTalent.UnActive;   //不需要激活，由客户端判定是否激活
        }

        if (lv >= config.maxLv) {
            return E_MsgCode.TalentLevelIsMax;
        }

        //天赋点
        const have = this.getUnUseTalentPoint(player);
        const cost = this.getTalentLevelUpCost(player, talentID);
        if (cost > have) {
            return E_ProtoTalent.TalentPointNotEnough;
        }

        return E_ProtoTalent.Success;
    }


    /**
     * 获取天赋解锁 or 升级消耗
     * @param player 
     * @param talentID 
     * @param level 
     * @returns 
     */
    public static getTalentLevelUpCost(player: Player, talentID: number, level?: number): number {
        const config = CDLordTalent.getData(talentID);
        if (config && config.pointCost.length > 0) {
            if (level === undefined || level === null) {
                level = player.talent.getTalentLevel(talentID) || 0;
            }
            if (level >= config.pointCost.length) {
                level = config.pointCost.length - 1;
            }
            if (level >= 0) {
                return config.pointCost[level];
            }
        }
        return 0;
    }


    /**
     * 未使用的天赋点
     * @param player 
     */
    public static getUnUseTalentPoint(player: Player): number {
        const lvConfig = CDUnitLv.getData(player.playerInfo.level);
        //天赋点 祝福加成
        let count = SDPray.getEffectByType(player, E_PrayEffectType.ExcessTalentPoint);
        //黄小西加成
        count += SDHuangXiaoxi.getEffectByType(player, E_PrayEffectType.ExcessTalentPoint);
        //等级 天赋点
        if (lvConfig) {
            count += lvConfig.talentPoint;
        }
        count -= player.talent.usePointCount;
        return count;
    }



}
